import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import util.DBConnection;

/**
 * This servlet is used to handle requests for changing administrator's password.
 * 
 * @author Josef Hardi
 *
 */
public class ChangePassword extends HttpServlet { 
	
	/** Database connection **/
   private Connection conn = null;	
	
   /**
	* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	*/
   public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException,IOException {
      
	  // Get the database connection
	  conn = DBConnection.getConnection();
	  
	  // Get the old password
      String oldPassword = request.getParameter("txt_old_password").toString();
      
      if(oldPassword != "" && oldPassword != null)
      {
    	  PreparedStatement stmt = null;
    	  ResultSet result = null;		
    	  try {
  			 // Search the user
  			 String query = "SELECT username " +
  			   		        "FROM UserRegister " +
  					        "WHERE password = ?";
  			
  			 stmt = conn.prepareStatement(query);
			 stmt.setString(1, MD5Sum(oldPassword));
			
			 // Begin querying
			 result = stmt.executeQuery();
			 
			 // If match!
			 if (result.next()) {
				 String newPassword = request.getParameter("txt_new_password").toString();
				 String retypePassword = request.getParameter("txt_retype_password").toString();
				 
				 // Check both passwords are equal
				 if (newPassword.equals(retypePassword)) {
					 updatePassword(newPassword);
					 
					 // Forward message: password changed!
					 request.setAttribute("errorMessage", "Password changed!"); 
		             RequestDispatcher rd=request.getRequestDispatcher("login.jsp");  
		             rd.forward(request, response);
				 }
				 else {
					 // Forward message: re-type password!
					 request.setAttribute("errorMessage", "Please re-type the new password correctly!");  
		             RequestDispatcher rd=request.getRequestDispatcher("change.jsp");  
		             rd.forward(request,response);  
				 }
             }
             else {
            	// Forward message: invalid password!
                request.setAttribute("errorMessage", "Invalid old password");  
                RequestDispatcher rd=request.getRequestDispatcher("change.jsp");  
                rd.forward(request,response);  
             }
    	  }
    	  catch (SQLException e) {
			 e.printStackTrace();
    	  } finally {
	    	 try {
	            // Close everything.
	            if (result!= null) result.close();
	            if (stmt!= null) stmt.close();
	            if (conn!= null) conn.close();
	    	 } catch (Exception e) { // Trap all other exceptions
                e.printStackTrace();
             }
	      }
      }
      else {
    	  response.sendRedirect("login.jsp");
      }
   }
	   
// ------------------------- PRIVATE METHODS ----------------------------   
	   
   /*
    * Update password.
    */
   private void updatePassword(String newPassword) throws SQLException {
	   
	  PreparedStatement stmt = null;
	  
	  // Update the new password
	  String query = "UPDATE UserRegister " +
	  		         "SET password = ? " +
	  		         "WHERE id = 1";
	  
	  stmt = conn.prepareStatement(query);
	  stmt.setString(1, MD5Sum(newPassword));
	  
	  // Execute update
	  stmt.executeUpdate();
   }
   
   /*
    * Procedure for encrypting string using MD5
    */
   private String MD5Sum(String input) {
	   
	  String hashtext = null;
	   
	  try {
		  MessageDigest md = MessageDigest.getInstance("MD5");
		  md.reset();
		  md.update(input.getBytes());
		  byte[] digest = md.digest();
		  BigInteger bigInt = new BigInteger(1, digest);
		  hashtext = bigInt.toString(16);
		  
		  // Now we need to zero pad it if you actually want the full 32 chars.
		  while(hashtext.length() < 32) {
		     hashtext = "0"+hashtext;
		  }
	   }
	   catch (NoSuchAlgorithmException e) { 
		   e.printStackTrace();
	   }
	   
	   return hashtext;
   }
   
}